package com.jzqf.bluetooth.client

import android.app.Service
import android.bluetooth.*
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.IBinder
import android.util.Log
import com.jzqf.bluetooth.Api
import com.jzqf.bluetooth.FormatUtil
import com.jzqf.bluetooth.event.EventCode
import com.jzqf.bluetooth.event.EventMessage
import org.greenrobot.eventbus.EventBus

/**
 *  蓝牙BLE客户端
 * 2020/9/30 13:49
 * @author LiuWeiHao
 */
class BleClientService : Service() {
    private val TAG = "【BleClient】"
    private var bluetoothGatt: BluetoothGatt? = null
    private var bluetoothAdapter: BluetoothAdapter? = null
    private var requestData = "34567"
    private var responseData: StringBuilder = StringBuilder()

    /**
     * 上次接收到的数据
     */
    private var mLastData: String? = null

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val bluetoothManager =
            this.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        bluetoothAdapter = bluetoothManager.adapter
        connect()
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    private var startTime = 0L

    /**
     * 开启连接
     */
    private fun connect() {
        startTime = System.currentTimeMillis()
        Log.d(TAG, "connect ")
        if (bluetoothAdapter == null || bluetoothAdapter?.isEnabled == false) {
//            val intentBlue = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
//            context.startActivityForResult(intentBlue, REQUEST_CODE_BLUE)
            Log.d(TAG, "蓝牙设备未启用")
            bluetoothAdapter?.enable()
            return
        }
        if (!this.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Log.d(TAG, "设备不支持BLE")
            EventBus.getDefault().post(EventMessage(EventCode.RESULT, "设备不支持BLE"))
            return
        }
        val bluetoothDevice = bluetoothAdapter!!.getRemoteDevice(Api.address)
        bluetoothGatt?.let {
            it.disconnect()
            it.close()
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            bluetoothGatt = bluetoothDevice.connectGatt(
                this, false, bluetoothGattCallback
//                , BluetoothDevice.TRANSPORT_LE
            )
        } else {
            bluetoothGatt = bluetoothDevice.connectGatt(
                this, false, bluetoothGattCallback
            )
        }
//        val requestMtu = bluetoothGatt?.requestMtu(Api.MAX_MTU)
//        Log.d(TAG, "requestMtu=$requestMtu")
    }


    private val bluetoothGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
        override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
            Log.d(TAG, "onConnectionStateChange status=$status,newstate=$newState")
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    //必须有，可以让onServicesDiscovered显示所有Services
                    gatt?.discoverServices()
                    Log.d(TAG, "时间=${System.currentTimeMillis() - startTime}")
                    EventBus.getDefault().post(EventMessage(EventCode.RESULT, "设备连接成功"))
                } else if (newState == BluetoothProfile.STATE_DISCONNECTING) {
                    EventBus.getDefault().post(EventMessage(EventCode.RESULT, "设备连接中..."))
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    EventBus.getDefault().post(EventMessage(EventCode.RESULT, "设备已断开连接"))
                    bluetoothGatt?.close()
                }
            } else {
                EventBus.getDefault().post(EventMessage(EventCode.RESULT, "设备连接失败:status=$status"))
            }
//            super.onConnectionStateChange(gatt, status, newState)
        }


        override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
            if (status != BluetoothGatt.GATT_SUCCESS) {
                Log.e(TAG, "onServicesDiscovered 失败 status=$status")
                return
            }
            val services: List<BluetoothGattService>? = bluetoothGatt?.services
            if (services.isNullOrEmpty()) {
                Log.e(TAG, "onServicesDiscovered services is null")
                return
            }
            for (gattService: BluetoothGattService in services) {
                if (gattService.uuid.toString().equals(Api.UUID_SERVICE.toString())) {
                    Log.d(TAG, "service uuid=${gattService.uuid}")
                }
                //根据约定的服务UUID拿到gatt服务
//                gattService.characteristics.forEach { characteristic ->
//                    when (characteristic.properties) {
//                        BluetoothGattCharacteristic.PROPERTY_READ -> {
//                            Log.d(
//                                TAG, "characteristics 可读 uuid=${characteristic.uuid}" +
//                                        "\n properties=${characteristic.properties}" +
//                                        "\n permissions=${characteristic.permissions}"
//                            )
//                        }
//                        BluetoothGattCharacteristic.PROPERTY_WRITE -> {
//                            Log.d(
//                                TAG, "characteristics 可写 uuid=${characteristic.uuid}" +
//                                        "\n properties=${characteristic.properties}" +
//                                        "\n permissions=${characteristic.permissions}"
//                            )
//                        }
//                        BluetoothGattCharacteristic.PROPERTY_NOTIFY -> {
//                            Log.d(
//                                TAG, "characteristics 通知 uuid=${characteristic.uuid}" +
//                                        "\n properties=${characteristic.properties}" +
//                                        "\n permissions=${characteristic.permissions}"
//                            )
//                        }
//                    }
//                }
            }
            write(requestData)
//            super.onServicesDiscovered(gatt, status)
        }

        override fun onCharacteristicChanged(
            gatt: BluetoothGatt?,
            characteristic: BluetoothGattCharacteristic
        ) { //数据改变
            responseServer(characteristic.value)
//            super.onCharacteristicChanged(gatt, characteristic)
        }

        override fun onCharacteristicRead(
            gatt: BluetoothGatt?,
            characteristic: BluetoothGattCharacteristic?,
            status: Int
        ) {
            Log.d(TAG, "onCharacteristicRead 接收数据:${characteristic?.value}")
//            super.onCharacteristicRead(gatt, characteristic, status)
        }

        override fun onCharacteristicWrite(
            gatt: BluetoothGatt?,
            characteristic: BluetoothGattCharacteristic?,
            status: Int
        ) {
            Log.d(
                TAG,
                "onCharacteristicWrite status=$status value=${String(characteristic?.value!!)}"
            )
            //修改 mDeviceBusy=false
            super.onCharacteristicWrite(gatt, characteristic, status)
            if (status == BluetoothGatt.GATT_SUCCESS) {
                //不为空则继续发送，发送完毕后要置空
                if (requestData.isNotEmpty()) {
                    writeLastData(requestData)
                }
            }
        }

        override fun onDescriptorRead(
            gatt: BluetoothGatt?,
            descriptor: BluetoothGattDescriptor?,
            status: Int
        ) {
            Log.d(TAG, "onDescriptorRead 收到=${descriptor?.value}")
//            super.onDescriptorRead(gatt, descriptor, status)
        }

        override fun onDescriptorWrite(
            gatt: BluetoothGatt?,
            descriptor: BluetoothGattDescriptor?,
            status: Int
        ) {
            Log.d(TAG, "onDescriptorWrite 写数据:${descriptor?.value}")
//            super.onDescriptorWrite(gatt, descriptor, status)
        }

        override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
            Log.d(TAG, "onMtuChanged mtu=$mtu status=$status")
//            super.onMtuChanged(gatt, mtu, status)
            if (status == BluetoothGatt.GATT_SUCCESS) {
                //重新设置mtu后重新发现服务
                gatt?.discoverServices()
            } else {
                gatt?.requestMtu(240)
            }
        }

        override fun onPhyRead(gatt: BluetoothGatt?, txPhy: Int, rxPhy: Int, status: Int) {
            Log.d(TAG, "onPhyRead ")
//            super.onPhyRead(gatt, txPhy, rxPhy, status)
        }

        override fun onPhyUpdate(gatt: BluetoothGatt?, txPhy: Int, rxPhy: Int, status: Int) {
            Log.d(TAG, "onPhyUpdate ")
//            super.onPhyUpdate(gatt, txPhy, rxPhy, status)
        }

        override fun onReadRemoteRssi(gatt: BluetoothGatt?, rssi: Int, status: Int) {
            Log.d(TAG, "onReadRemoteRssi ")
//            super.onReadRemoteRssi(gatt, rssi, status)
        }

        override fun onReliableWriteCompleted(gatt: BluetoothGatt?, status: Int) {
            Log.d(TAG, "onReliableWriteCompleted ")
//            super.onReliableWriteCompleted(gatt, status)
        }
    }

    /**
     * 加入标签拼接,写入数据
     */
    fun write(data: String) {
        val newData = "${Api.FLAG_START}$data${Api.FLAG_END}"
        val hexString = FormatUtil.stringToHexString(data)
        writeLastData(newData)
    }

    /**
     * 写入剩余数据
     */
    private fun writeLastData(lastData: String) {
        if (lastData.length > Api.MAX_MTU) {
            val tempStr = lastData.substring(0, Api.MAX_MTU)
            requestData = lastData.substring(Api.MAX_MTU, lastData.length)
            writeByCharacteristic(tempStr)
        } else {
            writeByCharacteristic(lastData)
            //待发送的数据置空,不再继续发送
            requestData = ""
            EventBus.getDefault().post(
                EventMessage(EventCode.RESULT, "发送成功")
            )
        }
//        bluetoothGatt?.disconnect()
    }

    /**
     * BluetoothGattCharacteristic必须重新生成，不可复用
     */
    private fun writeByCharacteristic(data: String) {
        if (bluetoothGatt == null) {
            Log.e(TAG, "characteristic() bluetoothGatt is null")
            return
        }
        val bluetoothGattService: BluetoothGattService? =
            bluetoothGatt!!.getService(Api.UUID_SERVICE)
        Log.e(
            TAG,
            "bluetoothGattService ${bluetoothGattService.toString()}"
        )
        if (bluetoothGattService == null) {
            Log.e(TAG, "bluetoothGattService is null")
            return
        }
        val bluetoothGattCharacteristicWrite =
            bluetoothGattService.getCharacteristic(Api.UUID_CHARACTERISTIC_WRITE)
        Log.d(
            TAG,
            "displayGattServices permissions=${bluetoothGattCharacteristicWrite?.permissions}," +
                    "properties=${bluetoothGattCharacteristicWrite?.properties}"
        )
        //启用或禁用给定特征的通知/指示。
        bluetoothGatt?.setCharacteristicNotification(bluetoothGattCharacteristicWrite, true)
//        bluetoothGattCharacteristicWrite?.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
        bluetoothGattCharacteristicWrite?.setValue(data)//直接发送字符串
//        bluetoothGattCharacteristicWrite?.setValue(FormatUtil.hexString2Bytes(data))//发送字节数组
        val writeCharacteristic =
            bluetoothGatt!!.writeCharacteristic(bluetoothGattCharacteristicWrite)
        Log.d(
            TAG,
            "写入:$writeCharacteristic,数据:${data}"
        )
    }


    private fun close() {
        bluetoothGatt?.disconnect()
        bluetoothGatt?.close()
        EventBus.getDefault().post(
            EventMessage(EventCode.RESULT, "连接已断开")
        )
    }

    /**
     * 处理服务端返回的数据
     */
    private fun responseServer(responseByteArray: ByteArray) {
        if (!dealResponseData(responseByteArray)) {
            return
        }
        EventBus.getDefault().post(EventMessage(EventCode.RESULT, "客户端收到:\n$responseData"))

    }

    /**
     * 根据每次返回的字节数拼接数据
     * 拼接完成返回true，否则返回false
     * @param responseByteArray 收到的字节数组
     */
    private fun dealResponseData(responseByteArray: ByteArray): Boolean {
        val hexString = FormatUtil.bytes2HexString(responseByteArray)
        Log.d(
            TAG, "收到的原始消息:${hexString},解析后:${FormatUtil.hexStringToString(hexString)}"
        )
        var resultStr = String(responseByteArray)
        if (mLastData.equals(resultStr)) {
            return false
        }
        if (resultStr.contains(Api.FLAG_START) || resultStr.contains(Api.FLAG_END)) {
            if (resultStr.contains(Api.FLAG_START) && resultStr.contains(Api.FLAG_END)) {
                //首次接收清除缓存
                responseData.clear()
                resultStr = resultStr.replace(Api.FLAG_START, "")
                resultStr = resultStr.replace(Api.FLAG_END, "")
                responseData.append(resultStr)
                return true
            }
            if (resultStr.contains(Api.FLAG_START)) {
                //首次接收清除缓存
                responseData.clear()
                responseData.append(resultStr.replace(Api.FLAG_START, ""))
            }
            if (resultStr.contains(Api.FLAG_END)) {
                responseData.append(resultStr.replace(Api.FLAG_END, ""))
                return true
            }
        } else {
            responseData.append(resultStr)
        }
        return false
    }


}